package procsim;

import java.util.*;

public class Signal implements Sig {
    private int val;
    private String name;
    private ArrayList<Updateable> elements;
    private ArrayList<Signal> signals;
    public Signal(int vrednost){
        set(vrednost);
    }
    public Signal(int vrednost, String nam){
        this(vrednost);
        name=nam;
    }
    public void addToSignalRegistry(){
        if(name!=null)
            SignalRegistry.addSignalValue(this);
    }
    @Override
    public int get(){
        return val;
    }
    @Override
    public Signal not(){
        val=Math.abs(val-1);
        applySignalToElements();
        return this;
    }
    public Signal negate(){ // isto sto i not, samo ne menja vrednost
        return new Signal(Math.abs(val-1), null);
    }
    @Override
    public String toString(){
        return name+":"+val;
    }
    @Override
    public String getName(){
        return name;
    }
    @Override
    public Signal setName(String str){
        name = str;
        return this;
    }
    @Override
    public boolean isNull(){
        return val==0;
    }
    public Signal set(int vrednost){
        return set(vrednost, true);
    }
    public Signal set(Signal sig){
        return set(sig, true);
    }
    public Signal set(int vrednost, boolean apply){
        if(val==vrednost) return this;
        if (vrednost!=0) val = 1;
        else val = 0;
        if(apply) applySignalToElements();
        return this;
    }
    public Signal set(Signal sig, boolean apply){
        if(sig==null || val==sig.get()) return this;
        val=sig.get();
        if(apply) applySignalToElements();
        return this;
    }
    public Signal link(Signal sig){ // A.link(B); kad se azurira A, azuirace se i B
        if(signals==null)
            signals = new ArrayList<Signal>();
        signals.add(sig);
        return this;
    }
    @Override
    public Signal addElement(Updateable elem){
        if(elements==null)
            elements = new ArrayList<Updateable>();
        if(!elements.contains(elem))
            elements.add(elem);
        return this;
    }
    private void applySignalToElements(){
        Iterator iter;
        if(elements!=null){
            iter = elements.iterator();
            while(iter.hasNext())
                ((Updateable)iter.next()).updateSignal(this);
        }
        if(signals!=null){
            iter = signals.iterator();
            while(iter.hasNext())
                ((Signal)iter.next()).set(this);
        }
    }
}
